#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "cJSON.h"

#define FileName "cfg.json"

struct _cfg {
    char devname[64];
    unsigned int enable;
    unsigned int magic;
    unsigned int version;
    unsigned int crcval;
}__;

struct _cfg usercfg = {{0}, 0};


int unserialize_numb_double(cJSON *f, char *item, double *val) {
    int ret = 0; 
    if(f != NULL) {
        cJSON *s = cJSON_GetObjectItem(f, item);
        if(s != NULL) {
            *val = cJSON_GetNumberValue(s);
            ret = 1;
        }
    }
    return ret;
}

int parse_numb(cJSON *f, char *item, uint32_t *val) {
    int ret = 0; 
    if(f != NULL) {
        cJSON *s = cJSON_GetObjectItem(f, item);
        if(s != NULL) {
            double number = cJSON_GetNumberValue(s);
            *val = (uint32_t)number;
            ret = 1;
        }
    }
    return ret;
}

int parse_str(cJSON *f, char *item, char* val) {
    int ret = 0; 
    if(f != NULL) {
        cJSON *s = cJSON_GetObjectItem(f, item);
        if(s != NULL) {
            char* src = cJSON_GetStringValue(s);
            if( NULL != strcpy(val, src)) {
                ret = 1;
            }
        }
    }
    return ret;
}

#define myarg(x) printf("%s = %ld\r\n", #x, x)
#define GET_NUM32(ITEM, p) parse_numb(root, ITEM, (uint32_t*)p)
#define GET_STR(ITEM, p) parse_str(root, ITEM, (char*)p)


void unserialize(char *text)
{
    cJSON *root = cJSON_Parse(text);
	if (!root) {
        printf("cJSON unserialize failed\n");
        return;
    }else {
        GET_STR("devname", &usercfg.devname);
        GET_NUM32("enable", &usercfg.enable);
        GET_NUM32("magic", &usercfg.magic);
        GET_NUM32("version", &usercfg.version);
        GET_NUM32("crcval", &usercfg.crcval);
	}
    printf("devname is %s\r\n", usercfg.devname);
    myarg(usercfg.enable);
    myarg(usercfg.magic);
    myarg(usercfg.version);
    myarg(usercfg.crcval);
    cJSON_Delete(root);
}

static void unserialize_file(const char* file_name)
{
	FILE *f; long len; char *data;
	f = fopen(file_name, "rb");
	fseek(f, 0, SEEK_END);
	len = ftell(f);
	fseek(f, 0, SEEK_SET);
	data = (char*)malloc(len + 1);
	fread(data, 1, len, f);
	fclose(f);
	unserialize(data);
	free(data);
}

void CJSON_CDECL json_cfg_init(void) {
    unserialize_file(FileName);
}

static int _json_save(cJSON *root)
{ 
#if 0    
    char *out = NULL;
    out = cJSON_Print(root); /*注意必须用了之后free*/
    printf("%ld :\n %s\n",strlen(out), out);
	FILE* fp = fopen(FileName ,"w+"); 	
	fprintf(fp, "%s", out);
    free(out);
	fclose(fp);
    return 0;
#else
    char *out = malloc(10*1024);
    if (!cJSON_PrintPreallocated(root, out, maxsize, 1)) {
        printf("cJSON Print failed!\n");
        return -1;
    }
    FILE* fp = fopen(FileName ,"w+"); 	
	fprintf(fp, "%s", out);
	fclose(fp);
    free(out);
#endif
    return 0;
}


/* Create a bunch of objects as demonstration. */
static void serialize(void)
{
    cJSON *root = NULL;
    cJSON *fields = NULL;
    cJSON *fld = NULL;
    int i = 0;
    root = cJSON_CreateObject();
    cJSON_AddNumberToObject(root, "Enable", usercfg.enable);
    cJSON_AddItemToObject(root, "fields", fields = cJSON_CreateArray());
 
    _json_save(root); 
}




int main(void)
{
    json_cfg_init();
    return 0;
}
